//
//  NetworkManager.m
//  PigMarket
//
//  Created by Felix on 2019/4/11.
//  Copyright © 2019 felix.pigmarket.oc. All rights reserved.
//

#import "NetworkManager.h"

#import "YYModel.h"
#import "URLRequestSerialization.h"

@interface NetworkManager()

@property(nonatomic,strong)NSURLSession *session;

@end

@implementation NetworkManager

+(instancetype)sharedInstance {
    
    static NetworkManager *instance = nil;
    static dispatch_once_t token;
    
    dispatch_once(&token,^{
        if(instance == nil){
            instance = [[NetworkManager alloc] init];
        }
    } );
    
    return instance;
}

- (instancetype)init {
    
    self = [super init];
    if (self) {
        
        NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
        sessionConfiguration.timeoutIntervalForRequest = 30;
        sessionConfiguration.timeoutIntervalForResource = 45;
        
        self.session = [NSURLSession sessionWithConfiguration:sessionConfiguration];
    }
    return self;
}

- (NSURLSessionDataTask *)sendRequest:(Request *)request
                    completionHandler:(void (^)(Response *response))completionHandler {
    
    PMLog(@"请求信息->request=%@",request);
    NSDictionary *parameters = nil;
    if (request.param) {
        parameters = [request.param yy_modelToJSONObject];
    }
    
    NSMutableURLRequest *mutableRequest = nil;
    NSError *error = nil;
    
    if ([request.method isEqualToString:kHTTPMethodPOST]) {
        mutableRequest = [[JSONRequestSerializer serializer] requestWithMethod:request.method URLString:request.URLString parameters:parameters error:&error];
    } else {
        mutableRequest = [[HTTPRequestSerializer serializer] requestWithMethod:request.method URLString:request.URLString parameters:parameters error:&error];
    }
    
    mutableRequest.allHTTPHeaderFields = request.headers;
    
    
    if (error) {
        Response *response = [Response responseWithCode:ResultCodeLocalHTTPRequestSerializerError msg:[error localizedDescription]];
        completionHandler(response);
        return nil;
    }
    
    NSURLSessionDataTask *task = [self.session dataTaskWithRequest:mutableRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable URLResponse, NSError * _Nullable error) {
        
        if (error) {//处理请求错误，错误码参考：<Foundation/NSURLError.h>
            
            Response *response = [Response responseWithCode:ResultCodeLocalHTTPURLError msg:[error localizedDescription]];
            PMLog(@"响应信息->response=%@,URLString=%@", response,request.URLString);
            completionHandler(response);
            return;
        }
        
        if (![URLResponse isKindOfClass:[NSHTTPURLResponse class]]) {
            
            Response *response = [Response responseWithCode:ResultCodeLocalHTTPURLError msg:@"response is not NSHTTPURLResponse"];
            PMLog(@"响应信息->response=%@,URLString=%@", response,request.URLString);
            completionHandler(response);
            
            return;
        }
        
        
        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) URLResponse;
        
        if (httpResponse.statusCode != 200 && httpResponse.statusCode != 401) {//处理非200和401状态码
            
            Response *response = [Response responseWithCode:ResultCodeLocalHTTPStatusError msg:[NSString stringWithFormat:@"httpResponse statusCode is %ld", (long)httpResponse.statusCode]];
            PMLog(@"响应信息->response=%@,URLString=%@", response,request.URLString);
            completionHandler(response);
            
            return;
        }
        
        
        NSError *jsonError = nil;
        
        id jsonData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&jsonError];
        
        if (jsonError) {//处理json解析错误
            
            Response *response = [Response responseWithCode:ResultCodeLocalHTTPResponseSerializerError msg:[error localizedDescription]];
            PMLog(@"响应信息->response=%@", response);
            completionHandler(response);
            
            return;
        }
        
        if (![jsonData isKindOfClass:[NSDictionary class]]) {
            
            Response *response = [Response responseWithCode:ResultCodeLocalHTTPResponseSerializerError msg:@"response data is not json object"];
            PMLog(@"响应信息->response=%@", response);
            completionHandler(response);
            
            return;
        }
        
        NSNumber *code = jsonData[@"code"];
        NSString *msg = jsonData[@"msg"];
        NSString *desc = jsonData[@"desc"];
        id dataObj = jsonData[@"data"];
        
        Response *response = [Response responseWithCode:code.integerValue msg:msg];
        response.desc = desc;
        
        PMLog(@"(%@)responseString = %@",[request URLString],[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        
        if (dataObj) {
            if([dataObj isKindOfClass:[NSDictionary class]]) {
                //返回数据为字典，即jsonObject
                response.data = [request.responseType yy_modelWithJSON:dataObj];
            } else if([dataObj isKindOfClass:[NSArray class]]) {
                //返回数据为数组，即jsonArray
//                response.data = [NSArray modelArrayWithClass:request.responseType array:dataObj];
                response.data = [NSArray yy_modelArrayWithClass:request.responseType json:dataObj];
            }
        }
        PMLog(@"响应信息->response=%@", response);
        completionHandler(response);
        
    }];
    
    [task resume];
    
    return task;
}


@end
